package com.ehi.tsconfig.service;

import org.apache.commons.exec.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.File;
import java.io.IOException;

public class ExecuteCmd {

    private static final Logger logger = LoggerFactory.getLogger(ExecuteCmd.class);
    private static ExecuteCmd instance;

    private int DEFAULT_TIME_OUT = 60 * 1000;

    private ExecuteCmd() {
    }

    public static ExecuteCmd getInstance() {
        if (instance == null)
            synchronized (ExecuteCmd.class) {
                if (instance == null)
                    instance = new ExecuteCmd();
            }
        return instance;
    }

    public ExecuteResult exeCmd(String cmd, int exitValue, boolean requerWatchDog) {
        CommandLine cmdL = new CommandLine(cmd);
        return exeCmd(cmdL, exitValue, null);
    }

    public ExecuteResult exeCmd(CommandLine cmd, int exitValue, File workingDir) {
        return exeCmdInternal(cmd, exitValue, true, DEFAULT_TIME_OUT, workingDir);
    }

    public ExecuteResult exeCmd(CommandLine cmd, int exitValue) {
        return exeCmdInternal(cmd, exitValue, true, DEFAULT_TIME_OUT, null);
    }

    public ExecuteResult exeCmd(CommandLine cmd, int exitValue, int timeout) {
        return exeCmdInternal(cmd, exitValue, true, timeout, null);
    }

    public ExecuteResult exeCmd(CommandLine cmd, int exitValue, int timeout, File workingDir) {
        return exeCmdInternal(cmd, exitValue, true, timeout, workingDir);
    }

    private ExecuteResult exeCmdInternal(CommandLine cmd, int exitValue, boolean requireWatchDog, int timeout, File workingDir) {
        ExecuteResult execResult = new ExecuteResult();
        final Executor executor = new DefaultExecutor();
        executor.setStreamHandler(new PumpStreamHandler(execResult));
        executor.setExitValue(exitValue);
        if (requireWatchDog && timeout > 0) {
            ExecuteWatchdog watchDog = new ExecuteWatchdog(timeout);
            executor.setWatchdog(watchDog);
        }
        if (workingDir != null) {
            executor.setWorkingDirectory(workingDir);
        }
        //DefaultExecuteResultHandler resultHandler = new DefaultExecuteResultHandler();
        try {
            int result = executor.execute(cmd);
            execResult.setExitValue(result);
        } catch (ExecuteException e) {
            execResult.setExitValue(e.getExitValue());
            logger.error("execute Excetpion:", e);
        } catch (IOException e) {
            execResult.setExitValue(-999);
            logger.error("excetpion:", e);
        } finally {
            logger.info("==============  Execute Output Begin  =====================");
            execResult.getLines().stream().forEach(res -> {
                logger.info(res);
            });
            logger.info("==============  Execute Output End  =====================");
            execResult.setWorkDir(executor.getWorkingDirectory());
        }
        return execResult;
    }
}
